//
//  GatherControlBar.m
//  YYTextTest
//
//  Created by macintosh on 16/9/12.
//  Copyright © 2016年 macintosh. All rights reserved.
//

#import "GatherControlBar.h"
#import "YYCGUtilities.h"

@interface GatherControlToggle : UIView
{
    CAShapeLayer *_dynamicBar;
}

@property (nonatomic, copy) void(^toggle)(BOOL isToggle);
@property (nonatomic, assign) NSTimeInterval duration;
@property (nonatomic, assign) BOOL isToggle;

@end

@implementation GatherControlToggle

- (instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
        UIImage *image = [self imageWithColor:[UIColor colorWithWhite:0 alpha:0.2] size:self.frame.size];
        
        UIButton *btn = [[UIButton alloc] initWithFrame:(CGRect){CGPointZero, frame.size}];
        [btn setImage:image forState:UIControlStateNormal];
        [btn addTarget:self action:@selector(btnClicked:) forControlEvents:UIControlEventTouchUpInside];
        [self addSubview:btn];
        
        CGFloat barW = CGRectGetHeight(frame);
        
        CAShapeLayer *stillBar = [CAShapeLayer layer];
        stillBar.frame = CGRectMake(barW * 0.25, barW * 0.5 - 1, barW * 0.5, 2);
        stillBar.fillColor = [UIColor whiteColor].CGColor;
        stillBar.strokeColor = stillBar.fillColor;
        stillBar.lineWidth = 2;
        stillBar.lineCap = kCALineCapRound;
        UIBezierPath *stillBarPath = [UIBezierPath bezierPath];
        [stillBarPath moveToPoint:CGPointMake(0, 1)];
        [stillBarPath addLineToPoint:CGPointMake(stillBar.bounds.size.width, 1)];
        stillBar.path = stillBarPath.CGPath;
        [self.layer addSublayer:stillBar];
        
        _dynamicBar = [CAShapeLayer layer];
        _dynamicBar.frame = CGRectMake(barW * 0.5 - 1, barW * 0.25, 2, barW * 0.5);
        _dynamicBar.fillColor = [UIColor whiteColor].CGColor;
        _dynamicBar.strokeColor = _dynamicBar.fillColor;
        _dynamicBar.lineCap = kCALineCapRound;
        _dynamicBar.lineWidth = 2;
        UIBezierPath *dynamicBarPath = [UIBezierPath bezierPath];
        [dynamicBarPath moveToPoint:CGPointMake(1, 0)];
        [dynamicBarPath addLineToPoint:CGPointMake(1, _dynamicBar.frame.size.height)];
        _dynamicBar.path = dynamicBarPath.CGPath;
        [self.layer addSublayer:_dynamicBar];
        
        _duration = 0.25;
        _isToggle = NO;
    }
    return self;
}

- (void)btnClicked:(UIButton *)btn
{
    btn.selected = !btn.isSelected;
    _isToggle = btn.isSelected;
    
    [CATransaction begin];
    [CATransaction setAnimationDuration:_duration];
    [CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];
    if (btn.isSelected) {
        _dynamicBar.transform = CATransform3DMakeRotation(M_PI_2, 0, 0, 1);
    } else {
        _dynamicBar.transform = CATransform3DIdentity;
    }
    [CATransaction commit];
    
    if (_toggle) {
        _toggle(btn.isSelected);
    }
}

- (UIImage *)imageWithColor:(UIColor *)color size:(CGSize)size {
    if (!color || size.width <= 0 || size.height <= 0) return nil;
    CGRect rect = CGRectMake(0.0f, 0.0f, size.width, size.height);
    UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, color.CGColor);
    CGContextAddArc(context, size.width * 0.5, size.width * 0.5, size.width * 0.5, 0, M_PI * 2, 0);
    CGContextFillPath(context);
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

@end

@interface GatherControlBar ()

@property (nonatomic, strong) CAShapeLayer *shapeLayer;
@property (nonatomic, strong) GatherControlToggle *toggle;
@property (nonatomic, strong) NSArray<UIButton *> *buttons;
@property (nonatomic, assign) CGFloat barWidth;
@property (nonatomic, assign) BOOL isPortrait;
@property (nonatomic, assign) CGRect foldedFrame;
@property (nonatomic, assign) BOOL isToggleFirst;

@end

@implementation GatherControlBar

+ (CGRect)adaptFrameForUnfoldedBarWithBarWidth:(CGFloat)width
                                   foldedFrame:(CGRect)frame
                                    isPortrait:(BOOL)isPortrait
                                       isFirst:(inout BOOL *)isFirst
{
    CGRect newFrame;
    
    if (isPortrait) {
        //portrait
        newFrame = CGRectMake(CGRectGetMinX(frame), CGRectGetMidY(frame) > kScreenHeight * 0.5 ? (*isFirst = NO,CGRectGetMaxY(frame) - width) : (*isFirst = YES, CGRectGetMinY(frame)), CGRectGetWidth(frame), width);
    } else {
        //landscape
        newFrame = CGRectMake(CGRectGetMidX(frame) > kScreenWidth * 0.5 ? (*isFirst = NO, CGRectGetMaxX(frame) - width) : (*isFirst = YES, CGRectGetMinX(frame)), CGRectGetMinY(frame), width, CGRectGetHeight(frame));
    }
    
    return newFrame;
}

+ (instancetype)gatherControlBarWithButtons:(NSArray<UIButton *> *)buttons frame:(CGRect)frame isPortrait:(BOOL)isPortrait
{
    BOOL isFirst;
    CGFloat barW = (buttons.count + 1) * frame.size.width * 1.5;
    CGRect newFrame = [GatherControlBar adaptFrameForUnfoldedBarWithBarWidth:barW foldedFrame:frame isPortrait:isPortrait isFirst:&isFirst];
    
    GatherControlBar *controlBar = [[GatherControlBar alloc] initWithFrame:newFrame];;
    controlBar.barWidth = barW;
    controlBar.isToggleFirst = isFirst;
    [controlBar updateLayoutWithFoldedFrame:frame isPortrait:isPortrait];
    controlBar.buttons = buttons;
    return controlBar;
}

- (instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
        _shapeLayer = [CAShapeLayer layer];
        _shapeLayer.frame = CGRectMake(0, 0, frame.size.width, frame.size.height);
        _shapeLayer.fillColor = [UIColor colorWithWhite:0 alpha:0.1].CGColor;
        _shapeLayer.strokeColor = _shapeLayer.fillColor;
        _shapeLayer.lineWidth = frame.size.width < frame.size.height ? CGRectGetWidth(frame) : CGRectGetHeight(frame);
        _shapeLayer.lineCap = kCALineCapRound;
        _shapeLayer.strokeStart = 0;
        _shapeLayer.strokeEnd = 0;
        [self.layer addSublayer:_shapeLayer];
        
        _isPortrait = YES;
        _duration = 0.25;
    }
    return self;
}

- (void)updateLayoutWithFoldedFrame:(CGRect)foldedFrame isPortrait:(BOOL)isPortrait
{
    _foldedFrame = foldedFrame;
    _isPortrait = isPortrait;
    
    self.frame = [GatherControlBar adaptFrameForUnfoldedBarWithBarWidth:_barWidth
                                                            foldedFrame:_foldedFrame
                                                             isPortrait:isPortrait
                                                                isFirst:&_isToggleFirst];
    
    [self addSubview:self.toggle];
}

- (void)layoutSubviews
{
    [super layoutSubviews];
    
    UIBezierPath *path = [UIBezierPath bezierPath];
    
    if (_isPortrait) {
        CGFloat btnW = CGRectGetWidth(self.frame);
        if (!_isToggleFirst) {
            
            
            [_buttons enumerateObjectsUsingBlock:^(UIButton * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                obj.transform = CGAffineTransformIdentity;
                obj.frame = CGRectMake(0, btnW * 0.5 + (1.5 * btnW) * idx, btnW, btnW);
            }];
            _toggle.frame = CGRectMake(0, CGRectGetHeight(self.frame) - btnW, btnW, btnW);
            
            [path moveToPoint:CGPointMake(CGRectGetMidX(self.bounds), CGRectGetHeight(self.bounds) - 0.5 * btnW)];
            [path addLineToPoint:CGPointMake(CGRectGetMidX(self.bounds), 0.5 * btnW)];
        } else {
            _toggle.frame = CGRectMake(0, 0, btnW, btnW);
            [_buttons enumerateObjectsUsingBlock:^(UIButton * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                obj.transform = CGAffineTransformIdentity;
                obj.frame = CGRectMake(0, CGRectGetMaxY(_toggle.frame) + 0.5 * btnW + (1.5 * btnW) * idx, btnW, btnW);
            }];
            
            [path moveToPoint:CGPointMake(CGRectGetMidX(self.bounds), 0.5 * btnW)];
            [path addLineToPoint:CGPointMake(CGRectGetMidX(self.bounds), CGRectGetHeight(self.bounds) - 0.5 * btnW)];
        }
    } else {
        CGFloat btnW = CGRectGetHeight(self.frame);
        if (!_isToggleFirst) {
            [_buttons enumerateObjectsUsingBlock:^(UIButton * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                obj.transform = CGAffineTransformIdentity;
                obj.frame = CGRectMake(btnW * 0.5 + (1.5 * btnW) * idx, 0, btnW, btnW);
            }];
            _toggle.frame = CGRectMake(CGRectGetWidth(self.frame) - btnW, 0, btnW, btnW);
            
            [path moveToPoint:CGPointMake(CGRectGetWidth(self.bounds) - 0.5 * btnW, CGRectGetMidY(self.bounds))];
            [path addLineToPoint:CGPointMake(0.5 * btnW, CGRectGetMidY(self.bounds))];
        } else {
            _toggle.frame = CGRectMake(0, 0, btnW, btnW);
            [_buttons enumerateObjectsUsingBlock:^(UIButton * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                obj.transform = CGAffineTransformIdentity;
                obj.frame = CGRectMake(CGRectGetMaxX(_toggle.frame) + 0.5 * btnW + (1.5 * btnW) * idx, 0, btnW, btnW);
            }];
            
            [path moveToPoint:CGPointMake(0.5 * btnW, CGRectGetMidY(self.bounds))];
            [path addLineToPoint:CGPointMake(CGRectGetWidth(self.bounds) - 0.5 * btnW, CGRectGetMidY(self.bounds))];
        }
    }
    
    _shapeLayer.path = path.CGPath;
    
    if (!_toggle.isToggle) {
        [_buttons enumerateObjectsUsingBlock:^(UIButton * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            obj.transform = CGAffineTransformMakeScale(0, 0);
        }];
    }
}

- (void)setButtons:(NSArray<UIButton *> *)buttons
{
    if (_buttons) {
        [_buttons enumerateObjectsUsingBlock:^(UIButton * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            [obj removeFromSuperview];
        }];
    }
    
    _buttons = buttons;
    
    if (!_buttons) return;
    
    [_buttons enumerateObjectsUsingBlock:^(UIButton * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        [self addSubview:obj];
    }];
}

- (GatherControlToggle *)toggle
{
    if (!_toggle) {
        _toggle = [[GatherControlToggle alloc] initWithFrame:(CGRect){CGPointZero, _foldedFrame.size}];
        __weak typeof(self) weakSelf = self;
        _toggle.toggle = ^(BOOL isToggle) {
            [UIView animateKeyframesWithDuration:weakSelf.duration delay:0 options:0 animations:^{
                if (isToggle) {
                    for (int i = 0; i < weakSelf.buttons.count; i ++) {
                        [UIView addKeyframeWithRelativeStartTime: (double)i / weakSelf.buttons.count
                                                relativeDuration: (double)1 / weakSelf.buttons.count
                                                      animations: ^{
                                                          UIButton *btn;
                                                          if (!weakSelf.isToggleFirst) {
                                                              btn = weakSelf.buttons[weakSelf.buttons.count - (i + 1)];
                                                          } else {
                                                              btn = weakSelf.buttons[i];
                                                          }
                                                          btn.transform = CGAffineTransformIdentity;
                                                      }];
                    }
                } else {
                    for (int i = 0; i < weakSelf.buttons.count; i ++) {
                        [UIView addKeyframeWithRelativeStartTime: (double)i / weakSelf.buttons.count
                                                relativeDuration: (double)1 / weakSelf.buttons.count
                                                      animations: ^{
                                                          UIButton *btn;
                                                          if (!weakSelf.isToggleFirst) {
                                                              btn = weakSelf.buttons[i];
                                                          } else {
                                                              btn = weakSelf.buttons[weakSelf.buttons.count - (i + 1)];
                                                          }
                                                          btn.transform = CGAffineTransformMakeScale(0, 0);
                                                      }];
                    }
                }
            } completion:nil];
            
            [CATransaction begin];
            [CATransaction setAnimationDuration:weakSelf.duration];
            if (isToggle) {
                weakSelf.shapeLayer.strokeEnd = 1;
            } else {
                weakSelf.shapeLayer.strokeEnd = 0;
            }
            [CATransaction commit];
        };
    }
    return _toggle;
}

@end
